<template>
    <div class="outbound-container">
        <!-- 选项卡 -->
        <el-tabs v-model="activeTabName" @tab-click="handleTabsChange">
            <el-tab-pane label="出库列表" name="todayList">
                <!-- 内容 -->
                <div :style="`width: ${outboundWidth};`">
                    <!-- 时间段出库列表容器 -->
                    <div class="w-full">
                        <!-- 选项 -->
                        <div class="flex justify-between items-center mb-2" style="height: 40px">
                            <el-date-picker
                                v-model="dataRange"
                                type="daterange"
                                range-separator="至"
                                start-placeholder="开始时间"
                                end-placeholder="结束时间"
                                @change="handleDateChange"
                            />
                            <el-button style="margin-left: 30px" type="primary" @click="exportOutboundByDataRangeEvent">按时间段导出</el-button>
                        </div>
                        <!-- 滚动条 -->
                        <el-scrollbar :height="'calc(100vh - 175px)'">
                            <!-- 出库列表样式 -->
                            <div v-if="outBoundList.length !== 0" class="flex flex-wrap content-start gap-2">
                                <!-- 出库列表 -->
                                <div v-for="(item, index) in outBoundList" class="w-full" :key="index">
                                    <!-- 描述列表 -->
                                    <el-descriptions :column="3" border label-width="100px">
                                        <template #title>
                                            出单时间：{{ formatTimeZone(item.createdAt, 'YYYY-MM-DD HH:mm:ss') }}
                                            <el-text size="large" :type="item.outbound ? 'success' : 'warning'">{{
                                                item.outbound ? '已结算' : '未结算'
                                            }}</el-text>
                                        </template>
                                        <template #extra>
                                            <el-button type="warning" @click="revokeOutboundEvent(item)">撤销出库</el-button>
                                            <el-button type="primary" @click="printDeliveryLabelEvent(item)">送货标签</el-button>
                                            <el-button type="primary" @click="printOutboundEvent(item)">前往出库</el-button>
                                        </template>
                                        <el-descriptions-item label="录入方式">{{
                                            item.createType == 'system' ? '系统' : '导入'
                                        }}</el-descriptions-item>
                                        <el-descriptions-item label="打印次数">{{ item.printTimes }}</el-descriptions-item>
                                        <el-descriptions-item label="制单人">
                                            {{ item.creator }}
                                        </el-descriptions-item>
                                        <el-descriptions-item :span="3" label="出库内容">
                                            <div v-for="(i, j) in item.orderData" :key="j" class="flex items-center gap-2">
                                                <!-- 订单号 -->
                                                <div>
                                                    <div v-if="j == 0">订单号：</div>
                                                    <div><el-input v-model="i.orderNo" disabled /></div>
                                                </div>
                                                <!-- 物料号 -->
                                                <div>
                                                    <div v-if="j == 0">物料号：</div>
                                                    <div><el-input v-model="i.materialNumber" disabled /></div>
                                                </div>
                                                <!-- 产品名称 -->
                                                <div>
                                                    <div v-if="j == 0">产品名称：</div>
                                                    <div><el-input v-model="i.productName" disabled /></div>
                                                </div>
                                                <!-- 产品尺寸 -->
                                                <div>
                                                    <div v-if="j == 0">产品尺寸：</div>
                                                    <div><el-input v-model="i.productSize" disabled /></div>
                                                </div>
                                                <!-- 订单数量 -->
                                                <div>
                                                    <div v-if="j == 0">订单数量：</div>
                                                    <div><el-input v-model="i.orderNumber" disabled /></div>
                                                </div>
                                                <!-- 送货数量 -->
                                                <div>
                                                    <div v-if="j == 0">送货数量：</div>
                                                    <div><el-input v-model="i.deliveryQuantity" disabled /></div>
                                                </div>
                                                <!-- 单位 -->
                                                <div>
                                                    <div v-if="j == 0">单位：</div>
                                                    <div><el-input v-model="i.unit" disabled /></div>
                                                </div>
                                                <!-- 单价 -->
                                                <div>
                                                    <div v-if="j == 0">单价：</div>
                                                    <div><el-input v-model="i.price" disabled /></div>
                                                </div>
                                                <!--  -->
                                            </div>
                                        </el-descriptions-item>
                                    </el-descriptions>
                                    <!-- 分割线 -->
                                    <el-divider>
                                        <el-icon>
                                            <StarFilled />
                                        </el-icon>
                                    </el-divider>
                                </div>
                            </div>
                            <!-- 空内容 -->
                            <el-empty v-if="outBoundList.length == 0" class="w-full" description="选择的时间段内没有出库记录" />
                        </el-scrollbar>
                    </div>
                </div>
            </el-tab-pane>
            <el-tab-pane label="客户列表" name="outboundList">
                <!-- 内容 -->
                <div class="flex flex-nowrap justify-between" :style="`width: ${outboundWidth};height: calc(100vh - 135px)`">
                    <!-- 左侧客户列表 -->
                    <CustomerList v-model="customerInfo" height="calc(100vh - 135px)" width="300px" customerAbbreviation></CustomerList>
                    <!-- 右侧展示容器 -->
                    <div v-if="customerInfo.customerId !== ''" :style="`width: ${customerListWidth};height: calc(100vh - 135px)`">
                        <!-- 选项列表容器 -->
                        <div style="height: 40px; display: flex; align-items: center">
                            <!-- 未发和已发切换 -->
                            <el-radio-group v-model="outbound" @change="handleRadioChange">
                                <el-radio :value="false">未发列表</el-radio>
                                <el-radio :value="true">已发列表</el-radio>
                            </el-radio-group>
                            <!-- 单据搜索 -->
                            <el-input
                                style="width: 200px; margin-left: 30px"
                                v-model="outboundIdValue"
                                placeholder="请输入出库单编号"
                                clearable
                                @change=""
                            ></el-input>
                            <!-- 按客户导出 -->
                            <el-button style="margin-left: 30px" type="primary" @click="exportOutboundByDataRangeEvent">按客户导出</el-button>
                        </div>
                        <!-- 客户出库列表容器 -->
                        <div :style="`width: ${customerListWidth};overflow: heidden;`">
                            <!-- 滚动条 -->
                            <el-scrollbar :height="'calc(100vh - 175px)'">
                                <!-- 出库列表样式 -->
                                <div class="flex flex-wrap content-start gap-2">
                                    <!-- 出库列表 -->
                                    <div v-for="(item, index) in outBoundList" class="w-full" :key="index">
                                        <!-- 描述列表 -->
                                        <el-descriptions :column="3" border label-width="100px">
                                            <template #title>
                                                出单时间：{{ formatTimeZone(item.createdAt, 'YYYY-MM-DD HH:mm:ss') }}
                                                <el-text size="large" :type="item.outbound ? 'success' : 'warning'">
                                                    {{ item.outbound ? '已结算' : '未结算' }}
                                                </el-text>
                                            </template>
                                            <template #extra>
                                                <el-button type="warning" @click="revokeOutboundEvent(item)">撤销出库</el-button>
                                                <el-button type="primary" @click="printDeliveryLabelEvent(item)" disabled>送货标签</el-button>
                                                <el-button type="primary" @click="printOutboundEvent(item)">前往出库</el-button>
                                            </template>
                                            <el-descriptions-item label="录入方式">
                                                {{ item.createType == 'system' ? '系统' : '导入' }}
                                            </el-descriptions-item>
                                            <el-descriptions-item label="打印次数">{{ item.printTimes }}</el-descriptions-item>
                                            <el-descriptions-item label="制单人">
                                                {{ item.creator }}
                                            </el-descriptions-item>
                                            <el-descriptions-item :span="3" label="出库内容">
                                                <div v-for="(i, j) in item.orderData" :key="j" class="flex items-center gap-2">
                                                    <!-- 订单号 -->
                                                    <div>
                                                        <div v-if="j == 0">订单号：</div>
                                                        <div><el-input v-model="i.orderNo" disabled /></div>
                                                    </div>
                                                    <!-- 物料号 -->
                                                    <div>
                                                        <div v-if="j == 0">物料号：</div>
                                                        <div><el-input v-model="i.materialNumber" disabled /></div>
                                                    </div>
                                                    <!-- 产品名称 -->
                                                    <div>
                                                        <div v-if="j == 0">产品名称：</div>
                                                        <div><el-input v-model="i.productName" disabled /></div>
                                                    </div>
                                                    <!-- 产品尺寸 -->
                                                    <div>
                                                        <div v-if="j == 0">产品尺寸：</div>
                                                        <div><el-input v-model="i.productSize" disabled /></div>
                                                    </div>
                                                    <!-- 订单数量 -->
                                                    <div>
                                                        <div v-if="j == 0">订单数量：</div>
                                                        <div><el-input v-model="i.orderNumber" disabled /></div>
                                                    </div>
                                                    <!-- 送货数量 -->
                                                    <div>
                                                        <div v-if="j == 0">送货数量：</div>
                                                        <div><el-input v-model="i.deliveryQuantity" disabled /></div>
                                                    </div>
                                                    <!-- 单价 -->
                                                    <div>
                                                        <div v-if="j == 0">单价：</div>
                                                        <div><el-input v-model="i.price" disabled /></div>
                                                    </div>
                                                    <!-- 小计 -->
                                                    <div>
                                                        <div v-if="j == 0">小计：</div>
                                                        <div><el-input v-model="i.subtotal" disabled /></div>
                                                    </div>
                                                </div>
                                            </el-descriptions-item>
                                            <el-descriptions-item :span="3" label="总金额">
                                                {{ item.orderData.reduce((pre, cur) => pre + cur.subtotal, 0) }}
                                            </el-descriptions-item>
                                        </el-descriptions>
                                        <!-- 分割线 -->
                                        <el-divider>
                                            <el-icon>
                                                <StarFilled />
                                            </el-icon>
                                        </el-divider>
                                    </div>
                                </div>
                            </el-scrollbar>
                        </div>
                    </div>
                    <!-- 空内容 -->
                    <el-empty
                        v-if="customerInfo.customerId == ''"
                        :style="`width: ${customerListWidth};height: calc(100vh - 135px)`"
                        description="请先选择一个客户来查看出库列表"
                    />
                </div>
            </el-tab-pane>
        </el-tabs>
    </div>

    <!-- OWN弹窗 -->
    <PrintOWNOutbound v-model:print-o-w-n-outbound-visible="printOWNOutboundVisible" :own-data="OWNData"></PrintOWNOutbound>
    <!-- OEM弹窗 -->
    <!-- 打印送货标签 -->
    <PrintDeliveryLabel
        v-model:print-delivery-label-visible="printDeliveryLabelVisible"
        :print-delivery-label-data="printDeliveryLabelData"
    ></PrintDeliveryLabel>
</template>

<script setup lang="ts">
import { cancelOutBound, getOutBoundList, getTodayOutBoundList } from '@/api/outbound';
import { formatTimeZone } from '@utils/calculate';
import PrintOWNOutbound from './components/PrintOWNOutbound.vue';
import { checkPermi } from '@utils/permission';
import { TabsPaneContext } from 'element-plus';
import { StarFilled } from '@element-plus/icons-vue';
import { getAllCustomerList } from '@/api/customer';
import dayjs from 'dayjs';
import * as xlsx from 'xlsx';
import { useSystemStore } from '@/store/modules/system';

onMounted(() => {
    // 获取时间段出库列表
    getTodayOutBoundListEvent();
    // 获取客户列表
    getAllCustomerList().then((res) => {
        if (res.data.length !== 0) {
            res.data.forEach((item) => {
                customerList.push(item);
            });
        }
    });
});

/* ***********************************通用属性/方法*********************************** */
// 客户出库列表数据
const outBoundList = reactive<AjaxResponse['outBoundList']>([]);
// tab选项切换
const handleTabsChange = (pane: TabsPaneContext) => {
    // 如果切换到时间段列表，清空客户列表
    if (pane.paneName === 'todayList') {
        getTodayOutBoundListEvent();
    } else {
        customerInfo.customerId = '';
        customerInfo.customerName = '';
        customerInfo.customerAbbreviation = '';
    }
};
// 所有客户信息
const customerList = reactive<AjaxResponse['customerList']>([]);

/* ***********************************时间段出库列表属性/方法*********************************** */
// 时间段 -- 前天到今天
const dataRange = ref<[Date, Date]>([new Date(new Date().getTime() - 3600 * 24 * 1000 * 2), new Date()]);
// tab选项
const activeTabName = ref('todayList');
// 获取时间段出库列表的方法
const getTodayOutBoundListEvent = () => {
    // 清空列表
    outBoundList.length = 0;
    // 获取时间段出库列表
    getTodayOutBoundList(dataRange.value).then((res) => {
        if (res.data.length !== 0) {
            res.data.forEach((item) => {
                outBoundList.push(item);
            });
        }
    });
};
// 时间段切换
const handleDateChange = () => {
    // 获取时间段出库列表
    getTodayOutBoundListEvent();
};
// 导出时间段出库列表
const exportOutboundByDataRangeEvent = () => {
    // 按客户名称分类
    const customerNameMap = new Map<string, AjaxResponse['outBoundList'][0][]>();
    outBoundList.forEach((item) => {
        const customerName = customerList.find((customer) => customer._id === item.customerId)!.customerName || '未知';
        if (customerNameMap.has(customerName)) {
            // @ts-ignore
            customerNameMap.get(customerName).push(item);
        } else {
            customerNameMap.set(customerName, [item]);
        }
    });

    // 按工作簿导出
    const wb = xlsx.utils.book_new();
    customerNameMap.forEach((value, key) => {
        // 从value中取出客户需要导出的资料
        const customerData: any = [];
        value.forEach((item) => {
            item.orderData.forEach((order) => {
                customerData.push({
                    送货日期: item.deliveryDate ? dayjs(item.deliveryDate).format('YYYY-MM-DD') : '未送货',
                    订单编号: order.orderNo,
                    物料号: order.materialNumber,
                    产品名称: order.productName,
                    产品尺寸: order.productSize,
                    订单数量: order.orderNumber,
                    送货数量: order.deliveryQuantity,
                    单位: order.unit,
                    单价: order.price,
                    金额: Number((order.deliveryQuantity * order.price).toFixed(2)),
                    备注: order.remark,
                });
            });
        });
        // 最后求和subtotal
        let sum = 0;
        customerData.forEach((item: any) => {
            sum += item.金额;
        });
        customerData.push({
            送货日期: '合计',
            订单编号: '',
            物料号: '',
            产品名称: '',
            产品尺寸: '',
            订单数量: '',
            送货数量: '',
            单位: '',
            单价: '',
            金额: sum,
            备注: '',
        });
        const ws = xlsx.utils.json_to_sheet(customerData);
        // 合计跨越两列
        ws['!merges'] = [{ s: { r: customerData.length, c: 0 }, e: { r: customerData.length, c: 1 } }];
        // 为每个单元格设置宽度
        ws['!cols'] = [
            { width: 12 }, // 送货日期
            { width: 20 }, // 订单编号
            { width: 15 }, // 物料号
            { width: 25 }, // 产品名称
            { width: 15 }, // 产品尺寸
            { width: 10 }, // 订单数量
            { width: 10 }, // 送货数量
            { width: 8 }, // 单位
            { width: 10 }, // 单价
            { width: 12 }, // 金额
            { width: 30 }, // 备注
        ];
        // 解析范围字符串
        // @ts-ignore
        const range = xlsx.utils.decode_range(ws['!ref']);
        // 遍历每个单元格
        for (let r = range.s.r; r <= range.e.r; r++) {
            for (let c = range.s.c; c <= range.e.c; c++) {
                const cell = xlsx.utils.encode_cell({ r, c });
                if (ws[cell]) {
                    // 为每个单元格设置边框
                    ws[cell].s = {
                        border: {
                            top: { style: 'thin', color: { rgb: '000000' } },
                            bottom: { style: 'thin', color: { rgb: '000000' } },
                            left: { style: 'thin', color: { rgb: '000000' } },
                            right: { style: 'thin', color: { rgb: '000000' } },
                        },
                    };
                }
            }
        }

        // 导出客户需要导出的资料
        xlsx.utils.book_append_sheet(wb, ws, key);
    });
    xlsx.writeFile(wb, `客户出库列表.xlsx`);
};

/* ***********************************客户出库列表属性/方法*********************************** */
// 获取客户列表点击的信息
const customerInfo = reactive({
    customerId: '',
    customerName: '',
    customerAbbreviation: '',
});
// 监听客户列表点击的信息
watch(
    () => customerInfo.customerId,
    (newValue) => {
        // 如果父组件传来客户id，，则调用更新订单列表的方法
        if (!newValue) {
            return;
        }
        // 调用获取出库列表的方法
        getOutBoundListEvent(newValue);
    }
);
// 客户出库列表选项 -- true 为已发列表，false 为未发列表
const outbound = ref(false);
// 获取客户出库列表的方法
const getOutBoundListEvent = (customerId: string) => {
    // 清空列表
    outBoundList.length = 0;
    // 获取客户出库列表
    getOutBoundList(customerId, outbound.value).then((res) => {
        if (res.data.length == 0) {
            ElMessage.warning(`该客户暂无${outbound.value ? '已发' : '未发'}出库记录`);
        } else {
            // 数据不能全给，会卡
            res.data.forEach((item) => {
                outBoundList.push(item);
            });
        }
    });
};
// 未发和已发切换
const handleRadioChange = () => {
    // 获取客户出库列表
    getOutBoundListEvent(customerInfo.customerId);
};

// 客户出库列表搜索框
const outboundIdValue = ref('');

/* ***********************************打印出库单属性/方法*********************************** */
// OWN打印dialog的可见性
const printOWNOutboundVisible = ref(false);
watch(
    () => printOWNOutboundVisible.value,
    (newValue) => {
        // OWN弹窗关闭时，重新加载数据
        if (!newValue) {
            // 如果是时间段列表，重新加载时间段列表
            if (activeTabName.value === 'todayList') {
                getTodayOutBoundListEvent();
                return;
            }
            getOutBoundListEvent(customerInfo.customerId);
        }
    }
);
// OWN打印的数据
const OWNData = ref<AjaxResponse['outBoundList'][0]>();

// OEM打印dialog的可见性
const printOEMOutboundVisible = ref(false);
// OEM打印的数据
const OEMData = ref<AjaxResponse['outBoundList'][0]>();

// 打印送货标签的dialog开关
const printDeliveryLabelVisible = ref(false);
// 打印送货标签的数据
const printDeliveryLabelData = ref<any>();

// 撤销出库单的方法
const revokeOutboundEvent = (item: AjaxResponse['outBoundList'][0]) => {
    // console.log(item);
    if (checkPermi(['warehouse:outbound'])) {
        ElMessageBox.confirm('确定要撤销该订单吗？', '系统提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        })
            .then(() => {
                cancelOutBound(item._id).then(() => {
                    ElMessage.success('撤销成功');
                    if (activeTabName.value === 'todayList') {
                        getTodayOutBoundListEvent();
                        return;
                    }
                    getOutBoundListEvent(customerInfo.customerId);
                });
            })
            .catch(() => {
                ElMessage.info('已取消');
            });
    } else {
        ElMessage.warning('您没有权限');
    }
};

// 送货标签的方法
const printDeliveryLabelEvent = (item: AjaxResponse['outBoundList'][0]) => {
    // 获取打印数据
    printDeliveryLabelData.value = item;
    printDeliveryLabelVisible.value = true;
};

// 打印出库单的方法
const printOutboundEvent = (item: AjaxResponse['outBoundList'][0]) => {
    // 选择哪种开单方式
    ElMessageBox.confirm('请先选择打印出库单方式', '系统提示', {
        confirmButtonText: '正常',
        cancelButtonText: '代开',
        type: 'warning',
    })
        .then(() => {
            // 获取打印数据
            OWNData.value = item;
            printOWNOutboundVisible.value = true;
        })
        .catch(() => {
            // 暂时不支持
            ElMessage({
                message: '暂不支持',
                type: 'warning',
            });
            // 获取打印数据
            OEMData.value = item;
            printOEMOutboundVisible.value = true;
        });
};

// 系统配置
const useSystem = useSystemStore();
// 计算宽度
const outboundWidth = computed(() => {
    return useSystem.config.isCollapse ? 'calc(100vw - 84px)' : 'calc(100vw - 220px)';
});
// 计算客户列表宽度
const customerListWidth = computed(() => {
    return useSystem.config.isCollapse ? 'calc(100vw - 384px)' : 'calc(100vw - 520px)';
});
</script>

<style scoped lang="scss">
.outbound-container {
    width: v-bind(outboundWidth);
    height: calc(100vh - 80px);
    display: flex;
}
</style>
